﻿using System;
using System.Collections.Generic;
using System.Text;
using NHibernate;
using NHibernate.Criterion;
using OpenGado.DATA.Entities;

namespace OpenGado.DATA
{
   public class IssueItemsDataControl
   {

       private static IssueItemsDataControl issueItemsDataControl;
       private  static object  lockIssueItems = new object();

       private ISession session;

       public  ISession Session
       {
           get
           {
               
                   session = FactoryHandler.CreateFactory().OpenSession();
             

               return session;
           }
       }

       public static IssueItemsDataControl Instance
       {
           get
           {
               lock(lockIssueItems)
               {
                   if (issueItemsDataControl ==null)
                   {
                       issueItemsDataControl = new IssueItemsDataControl();
                       
                   }
                   return issueItemsDataControl;
               }

           }
       }
       public  void SaveHeader (IssueItemHeader issueItemHeader)
       {
           ITransaction transaction = null;
           ISession tsession = Session;

           try
           {
               transaction = tsession.BeginTransaction();
               tsession.SaveOrUpdate(issueItemHeader);
               transaction.Commit();
           }
           catch (Exception)
           {
               if (transaction != null) transaction.Rollback();
               throw;
           }
           finally
           {
               tsession.Close();
           }
       }
       /// <summary>
       /// Deletes issue item header (and subitems)
       /// </summary>
       /// <param name="issueItemHeader"></param>
       public void DeleteHeader (IssueItemHeader issueItemHeader)
       {
           ISession tsession = Session;
           ITransaction transaction = null;
           transaction = tsession.BeginTransaction();

           int issueHeaderId = issueItemHeader.IssueItemHeaderId;

           // get it from the database then only delete it.
           issueItemHeader = IssueItemsDataControl.Instance.GetIssueHeader(issueHeaderId);

           try
           {
               tsession.Delete(issueItemHeader);
               transaction.Commit();
               
           }
           catch (Exception)
           {
               transaction.Rollback();
               throw;
           }
            finally

           {
               tsession.Close();
           }
         
       }

       /// <summary>
       /// Saves issue item
       /// </summary>
       /// <param name="issueItem"></param>
       public  void Save(IssueItem issueItem)
       {
           ITransaction transaction = null;
           ISession tsession = Session; 

           try
           {
               transaction = tsession.BeginTransaction();
               tsession.SaveOrUpdate(issueItem);
               transaction.Commit();
           }
           catch (Exception)
           {
               if (transaction != null) transaction.Rollback();
               throw;
           }
           finally
           {
               tsession.Close();
           }

       }
       /// <summary>
       /// Saves item header 
       /// </summary>
       /// <param name="itemHeader"></param>
       public void Save (IssueItemHeader itemHeader)
       {
           ITransaction transaction = null;
           ISession tsession = Session;
           transaction = tsession.BeginTransaction();

           try
           {
               tsession.SaveOrUpdate(itemHeader);
               transaction.Commit();
           }
           catch (Exception)
           {

               transaction.Rollback();
           }
           finally
           {
               tsession.Close();
           }


       }

       public void Save(IssueItemHeader itemHeader, List<RequestItem> requestItems)
       {
           ITransaction transaction = null;

           ISession tsession = Session;

           transaction = tsession.BeginTransaction();

         //  itemHeader.RequestItem = requestItems;

           try
           {
               tsession.SaveOrUpdate(itemHeader);


               if (requestItems != null)
                   foreach (RequestItem i in requestItems)
                   {
                       i.IssueItemHeader = itemHeader;

                       tsession.SaveOrUpdate(i);
                     
                   }


               transaction.Commit();

           }
           catch (Exception)
           {
               transaction.Rollback();
               throw;
           }
           finally
           {
               tsession.Close();
           }

       }

       public int GetNextId()
       {
           int nextId =0;
           ISession tsession = Session;
          
           IQuery query = tsession.CreateSQLQuery("SELECT MAX(issue_item_header_id) FROM issue_item_header");
           nextId = (int)query.UniqueResult();
           nextId++;

           return nextId;
       }
       public void Save(IssueItemHeader itemHeader, List<IssueItem> itemList)
       {
           ITransaction transaction = null;

           ISession tsession = Session;

           transaction = tsession.BeginTransaction();

           try
           {
               tsession.SaveOrUpdate(itemHeader);
          

               if (itemList != null)
                   foreach (IssueItem i in itemList)
                   {
                       tsession.SaveOrUpdate(i);
                       i.Product.ProductQuantity = (i.Product.ProductQuantity - i.IssueQuantity);
                       
                       tsession.SaveOrUpdate(i.Product);
                   }


               transaction.Commit();

           }
           catch (Exception)
           {
               transaction.Rollback();
               throw;
           }
           finally
           {
               tsession.Close();
           }

       }

       /// <summary>
       /// Returns all Issue header items based on search string
       /// </summary>
       /// <returns></returns>
       public IList<IssueItemHeader> GetListOfHeaders(DateTime startDate, DateTime endDate)
       {
        
           ISession tsession = Session;

           IList<IssueItemHeader> issueItemHeaders = new List<IssueItemHeader>();
           try
           {
               
                    ICriteria criteria = tsession.CreateCriteria<IssueItemHeader>();
                    criteria.Add(Restrictions.Between("RequestDate", startDate, endDate));
                   
                    issueItemHeaders = criteria.List<IssueItemHeader>();

              
             
           }
           catch (Exception)
           {
               
             
           }
           tsession.Close();

           return issueItemHeaders;
       }

       /// <summary>
       /// Returns all Issue header items based on search string
       /// </summary>
       /// <returns></returns>
       public IList<IssueItemHeader> GetListOfHeaders(string propertyName, string propertyValue)
       {
          
           ISession tsession = Session;
           IList<IssueItemHeader> issueItemHeaders = new List<IssueItemHeader>();

           IssueItemHeader i = new IssueItemHeader();

           
           try
           {
               ICriteria criteria = tsession.CreateCriteria<IssueItemHeader>();
              
               if (propertyName ==null)
               {
                 
                   issueItemHeaders = criteria.List<IssueItemHeader>();

               }
               else
               {

                   if (propertyName == "Project")
                   {
                       criteria.CreateCriteria("Project")
                        .Add(Restrictions.Like("Name", propertyValue + "%"));
                   }
                   else
                   {
                       
                       criteria = tsession.CreateCriteria<IssueItemHeader>()
                           .Add(Restrictions.Like(propertyName, propertyValue +"%"));

                   }
                           
                   issueItemHeaders = criteria.List<IssueItemHeader>();
              
               }
             
           }
           catch (Exception)
           {
               
             
           }
           tsession.Close();

           return issueItemHeaders;
       }

       /// <summary>
       /// Returns a list of all headers. 
       /// </summary>
       /// <returns></returns>
        public IList<IssueItemHeader> GetListOfHeaders()
       {
           //Todo: add per project return type
           ISession tsession = Session;
           IList<IssueItemHeader> issueItemHeaders = new List<IssueItemHeader>();
           try
           {
               
                   ICriteria criteria = tsession.CreateCriteria<IssueItemHeader>();
                   issueItemHeaders = criteria.List<IssueItemHeader>();

             
           }
           catch (Exception)
           {
               
             
           }
           tsession.Close();

           return issueItemHeaders;
       }

       /// <summary>
       /// Returns all Issue header items
       /// </summary>
       /// <returns></returns>
       public IList<IssueItemHeader> HeaderQuery(String fieldName, string fieldValue, DateTime startDate, DateTime endDate)
       {
         
           ISession tsession = Session;
           
           ICriteria criteria = tsession.CreateCriteria<IssueItemHeader>();

           switch (fieldName)
           {
               case "Project":
                   {
                       criteria.CreateCriteria("Project")
                           .Add(Restrictions.Like("Name", fieldValue +"%"));
                       break;
                   }

               case "RequestStatus":
                   {
                       criteria.Add(Restrictions.Eq("RequestStatus", fieldValue));
                       break;
                   }
               
           }
        
        
           IList<IssueItemHeader> issueItemHeaders = criteria.List<IssueItemHeader>();

            tsession.Close();

           return issueItemHeaders;
       }

       /// <summary>
       /// Returns a particular Issue header item
       /// </summary>
       /// <param name="headerId"></param>
       /// <returns></returns>
       public IssueItemHeader GetIssueHeader(int headerId)
       {
           ISession tsession = this.Session;

           IssueItemHeader header =   tsession.Get<IssueItemHeader>(headerId);
          
           tsession.Close();

           return header;
       }

       
       /// <summary>
       /// Will find teh requestID and return Issue Item header object.
       /// </summary>
       /// <param name="requestId"></param>
       /// <returns></returns>
       public IssueItemHeader GetIssueHeaderByRequestId(String requestId)
       {
           int headerId;
           int.TryParse(requestId, out headerId);

           ISession tsession = Session;
           ICriteria criteria = tsession.CreateCriteria<IssueItemHeader>()
               .Add(Restrictions.Eq("IssueItemHeaderId", headerId ));
           IList<IssueItemHeader> headerList =  criteria.List<IssueItemHeader>();

           IssueItemHeader header =  headerList[0];

           return header;
       }

       /// <summary>
       ///  Deletes issue item from db
       /// </summary>
       /// <param name="issueItem"></param>
       public  void Delete (IssueItem issueItem)
       {
           ITransaction transaction = null;
           ISession tsession = Session;
           try
           {
               transaction = tsession.BeginTransaction();
               tsession.Delete(issueItem);
               transaction.Commit();
           }
           catch (Exception)
           {
               if (transaction != null) transaction.Rollback();
               throw;
           }  
       }


   }
}
